/*
 * *******************************************************************
 *   @项目名称: BHex Android
 *   @文件名称: StepView.java
 *   @Date: 18-11-29 下午4:05
 *   @Author: ppzhao
 *   @Description:
 *   @Copyright（C）: 2018 BlueHelix Inc.   All rights reserved.
 *   注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的.
 *  *******************************************************************
 */

package io.bhex.app.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import io.bhex.app.R;

/**
 * ================================================
 * 描   述：步长可拖动进度条
 * ================================================
 */

public class StepView extends View {
    private static final String TAG = "StepView";
    //背景进度条颜色
    private int bgLineColor;
    //前景进度条颜色
    private int foreLineColor;
    //背景小圆颜色
    private int bgSmallCircleColor;
    //前景小圆颜色
    private int foreSmallCircleColor;
    //前景大圆颜色
    private int foreBigCircleColor;
    //背景线高
    private float bgLineHeight;
    //前景线高
    private float foreLineHeight;

    //背景小圆半径
    private float bgSmallRadius;
    //前景小圆半径
    private float foreSmallRadius;
    //前景大圆半径
    private float foreBigRadius;
    //view高度
    private int viewHeight;
    //view宽度
    private int viewWidth;
    //步数
    private int mStepNum;
    //Y轴中心坐标
    private int centerY;
    //每步长度
    private float perStepX;
    //进度 0-1
    private float mProgress;
    //进度宽 此处是加上开始的边距
    private float progressWidth;
    //X绘制开始点
    private float startX;
    //X绘制结束点
    private float stopX;
    //进度监听器
    private StepViewProgressListener mProgressListener;
    //进度条View总长度
    private float progressViewTotalLength;
    private Paint paint;
    private StepTouchListener mTouchListener;

    public StepView(Context context) {
        this(context, null);
    }

    public StepView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StepView);
        mStepNum = typedArray.getInteger(R.styleable.StepView_steps_num, 2);
        mProgress = typedArray.getFloat(R.styleable.StepView_progress, 0f);
        bgSmallRadius = typedArray.getDimension(R.styleable.StepView_background_small_circle_radius, 20);
        foreSmallRadius = typedArray.getDimension(R.styleable.StepView_foreground_small_circle_radius, 20);

        bgLineHeight = typedArray.getDimension(R.styleable.StepView_background_line_hight, 2);
        foreLineHeight = typedArray.getDimension(R.styleable.StepView_foreground_line_hight, 2);
        foreBigRadius = typedArray.getDimension(R.styleable.StepView_foreground_big_circle_radius, 20);
        bgLineColor = typedArray.getColor(R.styleable.StepView_background_line_color, getResources().getColor(R.color.divider_line_color));
        foreLineColor = typedArray.getColor(R.styleable.StepView_foreground_line_color, getResources().getColor(R.color.divider_line_color));
        bgSmallCircleColor = typedArray.getColor(R.styleable.StepView_background_small_circle_color, getResources().getColor(R.color.divider_line_color));
        foreSmallCircleColor = typedArray.getColor(R.styleable.StepView_foreground_small_circle_color, getResources().getColor(R.color.divider_line_color));
        foreBigCircleColor = typedArray.getColor(R.styleable.StepView_foreground_big_circle_color, getResources().getColor(R.color.divider_line_color));
        typedArray.recycle();
        setWillNotDraw(false);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        paint = new Paint();
        viewHeight = getHeight();
        viewWidth = getWidth();
        startX = foreBigRadius;
        stopX = viewWidth - foreBigRadius;
        progressViewTotalLength = stopX - startX;
        centerY = viewHeight / 2;
        perStepX = (progressViewTotalLength) / (mStepNum - 1);
    }

    /**
     * 改变字体颜色
     * @param viewBgLineColor
     * @param viewForeLineColor
     * @param viewBgSmallCircleColor
     * @param viewForeSmallCircleColor
     * @param viewForeBigCircleColor
     */
    public void changeColor(int viewBgLineColor,int viewForeLineColor,int viewBgSmallCircleColor,int viewForeSmallCircleColor,int viewForeBigCircleColor){
        bgLineColor = viewBgLineColor;
        foreLineColor = viewForeLineColor;
        bgSmallCircleColor = viewBgSmallCircleColor;
        foreSmallCircleColor = viewForeSmallCircleColor;
        foreBigCircleColor = viewForeBigCircleColor;
        invalidate();
    }

    public void setBgSmallCircleColor(int viewBgLineColor,int viewBgSmallCircleColor){
        bgLineColor = viewBgLineColor;
        bgSmallCircleColor = viewBgSmallCircleColor;
        invalidate();
    }

    public void setStepCount(int stepNum) {
        mStepNum = stepNum;
    }

    /**
     * 设置进度宽 范围（0-1）
     *
     * @param progress
     */
    public void setStepProgress(float progress) {
        if (progress>1) {
            progress =1;
        }
        if (progress<0) {
            progress =0;
        }
        mProgress = progress;
        invalidate();
    }

    public float getStepProgress(){
        return mProgress;
    }

    /**
     * 设置进度监听
     *
     * @param listener
     */
    public void setOnProgressListener(StepViewProgressListener listener) {
        mProgressListener = listener;
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        viewWidth = w;
        viewHeight = h;
        updateConfig();
    }

    private void updateConfig() {
        startX = foreBigRadius;
        stopX = viewWidth - foreBigRadius;
        centerY = viewHeight / 2;
        progressViewTotalLength = stopX - startX;
        perStepX = (progressViewTotalLength) / (mStepNum - 1);
        progressWidth = (stopX - startX) * mProgress + startX;
//        DebugLog.e(TAG, "centerY:" + centerY + " perStepX:" + perStepX + "  mProgress:" + mProgress);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        updateConfig();
        drawBgLine(canvas);
        drawBgCircle(canvas);
        //判断如果有进度再绘制进度
        if (mProgress > 0) {
            drawForeLine(canvas);
        }

        drawForeCircle(canvas);

    }

    /**
     * 绘制前景圆
     */
    private void drawForeCircle(Canvas canvas) {
        float cx, cy = centerY;
//        Paint paint = new Paint();
        paint.setAntiAlias(true);
//        paint.setStyle(Paint.Style.STROKE);

        paint.setColor(foreSmallCircleColor);

        for (int i = 0; i < mStepNum; i++) {
            cx = startX + i * perStepX;
//            DebugLog.e(TAG, "cx" + cx + "  cy:" + cy);
            if (cx <= progressWidth) {
                canvas.drawCircle(cx, cy, foreSmallRadius, paint);
            }
        }
//        //判断如果进度节点不在整数步长上，则需要再次绘制一个进度点的小圆
//        if ((progressWidth - startX) % perStepX != 0) {
//            canvas.drawCircle(progressWidth, cy, foreSmallRadius, paint);
//        }

        //绘制大圆
        paint.setColor(bgSmallCircleColor);
        canvas.drawCircle(progressWidth, cy, foreBigRadius, paint);
//        canvas.drawCircle(progressWidth, cy, foreBigRadius+1, paint);
        paint.setColor(foreBigCircleColor);
        canvas.drawCircle(progressWidth, cy, foreBigRadius, paint);
        paint.setColor(foreSmallCircleColor);
        canvas.drawCircle(progressWidth, cy, foreSmallRadius, paint);


    }

    /**
     * 绘制前景进度条
     *
     * @param canvas
     */
    private void drawForeLine(Canvas canvas) {
//        Paint mPaintLine = new Paint();
        paint.setStrokeWidth(foreLineHeight);
        paint.setAntiAlias(true);
        paint.setColor(foreLineColor);
        canvas.drawLine(startX, centerY, progressWidth, centerY, paint);
    }

    /**
     * 绘制背景小圆
     *
     * @param canvas
     */
    private void drawBgCircle(Canvas canvas) {

        paint.setAntiAlias(true);
//        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(bgSmallCircleColor);

        float cx, cy = centerY;
        for (int i = 0; i < mStepNum; i++) {
            cx = startX + i * perStepX;
//            DebugLog.e(TAG, "cx" + cx + "  cy:" + cy);
            canvas.drawCircle(cx, cy, bgSmallRadius, paint);
        }

    }

    /**
     * 绘制背景进度条
     *
     * @param canvas
     */
    private void drawBgLine(Canvas canvas) {
//        Paint mPaintLine = new Paint();
        paint.setStrokeWidth(bgLineHeight);
        paint.setAntiAlias(true);
        paint.setColor(bgLineColor);
        canvas.drawLine(startX, centerY, stopX, centerY, paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                //长安状态下  先请求 父 View不要拦截事件
                getParent().requestDisallowInterceptTouchEvent(true);
                float lastX = event.getX();
                if (mTouchListener != null) {
                    mTouchListener.onTouchDown();
                }
                updateProgress(lastX);
            }
            break;

            case MotionEvent.ACTION_MOVE: {
                float thisX = event.getX();
                updateProgress(thisX);
            }
            break;
            case MotionEvent.ACTION_UP:
                getParent().requestDisallowInterceptTouchEvent(false);
                if (mTouchListener != null) {
                    mTouchListener.onTouchUp();
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_OUTSIDE:
                if (mTouchListener != null) {
                    mTouchListener.onTouchUp();
                }
                break;
        }
        return true;
    }



    /**
     * 更新进度
     *
     * @param lastX
     */
    private void updateProgress(float lastX) {
//        DebugLog.e(TAG, "lastX: " + lastX);
        //边界值判断
        if (lastX <= startX) {
            lastX = startX;
        } else if (lastX >= stopX) {
            lastX = stopX;
        }
        progressWidth = lastX;
        mProgress = (progressWidth - startX) / progressViewTotalLength;
        postInvalidate();
        if (mProgressListener != null) {
            mProgressListener.onStepViewProgress(mProgress);
        }

    }

    /**
     * 设置触摸监听
     * @param listener
     */
    public void setStepTouchListener(StepTouchListener listener){
        mTouchListener = listener;
    }

    /**
     * 触摸监听
     */
    public interface StepTouchListener {
        void onTouchDown();
        void onTouchUp();
    }

    /**
     * 进度监听
     */
    public interface StepViewProgressListener {
        void onStepViewProgress(float progress);
    }
}
